home *** CD-ROM | disk | FTP | other *** search
/ Collection of Internet / Collection of Internet.iso / infosrvr / dev / www_talk.930 / 000333_marca@wintermu….ncsa.uiuc.edu _Wed Nov 18 02:11:38 1992.msg < prev    next >
Internet Message Format  |  1994-01-24  |  19KB

  1. Return-Path: <marca@wintermute.ncsa.uiuc.edu>
  2. Received: from dxmint.cern.ch by  nxoc01.cern.ch  (NeXT-1.0 (From Sendmail 5.52)/NeXT-2.0)
  3.     id AA06574; Wed, 18 Nov 92 02:11:38 MET
  4. Received: by dxmint.cern.ch (dxcern) (5.57/3.14)
  5.     id AA29817; Wed, 18 Nov 92 02:24:36 +0100
  6. Received: from wintermute.ncsa.uiuc.edu by newton.ncsa.uiuc.edu with SMTP id AA05259
  7.   (5.65a/IDA-1.4.2 for www-talk@nxoc01.cern.ch); Tue, 17 Nov 92 19:23:48 -0600
  8. Received: by wintermute.ncsa.uiuc.edu (920110.SGI/911001.SGI)
  9.     for @newton.ncsa.uiuc.edu:www-talk@nxoc01.cern.ch id AA05780; Tue, 17 Nov 92 19:24:59 -0800
  10. Date: Tue, 17 Nov 92 19:24:59 -0800
  11. From: marca@ncsa.uiuc.edu (Marc Andreessen)
  12. Message-Id: <9211180324.AA05780@wintermute.ncsa.uiuc.edu>
  13. To: www-talk@nxoc01.cern.ch
  14. Subject: html-mode.el
  15.  
  16. OK, here's a first pass at an html-mode for Emacs.  Comments, bug
  17. reports, and enhancements are welcome; the latest version will always
  18. be on ftp.ncsa.uiuc.edu in /outgoing/marca as html-mode.el.
  19.  
  20. (Somebody already sent me an smgl-mode.el, so I expect I'll add
  21. features from that pretty quickly.)
  22.  
  23. Enjoy,
  24.  
  25. Marc
  26.  
  27. --
  28. Marc Andreessen
  29. Software Development Group
  30. National Center for Supercomputing Applications
  31. marca@ncsa.uiuc.edu
  32.  
  33.  
  34. ;;; --------------------------------------------------------------------------
  35. ;;; HTML mode, based on text mode.
  36. ;;; Copyright (C) 1985 Free Software Foundation, Inc.
  37. ;;; Copyright (C) 1992 National Center for Supercomputing Applications.
  38. ;;; NCSA modifications by Marc Andreessen (marca@ncsa.uiuc.edu).
  39. ;;;
  40. ;;; This program is free software; you can redistribute it and/or
  41. ;;; modify it under the terms of the GNU General Public License as
  42. ;;; published by the Free Software Foundation; either version 1, or
  43. ;;; (at your option) any later version.
  44. ;;;
  45. ;;; This program is distributed in the hope that it will be useful,
  46. ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  47. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  48. ;;; General Public License for more details.
  49. ;;;
  50. ;;; You should have received a copy of the GNU General Public License
  51. ;;; along with GNU Emacs; see the file COPYING.  If not, write to the
  52. ;;; Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  53. ;;;
  54. ;;; -------------------------------- CONTENTS --------------------------------
  55. ;;;
  56. ;;; html-mode: Major mode for editing HTML hypertext documents.
  57. ;;; $Revision: 1.11 $
  58. ;;; $Date: 1992/11/18 03:20:43 $
  59. ;;;
  60. ;;; Canonical list of features:
  61. ;;;   See below.
  62. ;;;
  63. ;;; ------------------------------ INSTRUCTIONS ------------------------------
  64. ;;;
  65. ;;; Load html-mode.el before editing HTML documents.  html-mode will
  66. ;;; detect the ``.html'' suffix and activate itself appropriately.
  67. ;;;
  68. ;;; You are assumed to be at least somewhat familiar with HTML format.
  69. ;;; If you aren't, read about it first (see below).
  70. ;;;
  71. ;;; Here are key sequences and corresponding commands (in order of
  72. ;;; their key sequences):
  73. ;;;
  74. ;;; C-c a         html-add-address
  75. ;;;   Open an address element.
  76. ;;;
  77. ;;; C-c d         html-add-definition-list
  78. ;;;   Open a definition list.  The initial entry is created for you.
  79. ;;;   To create subsequent entries, use 'C-c e'.
  80. ;;;
  81. ;;; C-c e         html-add-definition-entry
  82. ;;;   Add a new definition entry in a definition list.  You are
  83. ;;;   assumed to be inside a definition list (specifically, at the end
  84. ;;;   of another definition entry).
  85. ;;;
  86. ;;; C-c h         html-add-header
  87. ;;;   Add a header.  You are prompted for size (1 is biggest, 2 is
  88. ;;;   next biggest) and header contents.
  89. ;;;
  90. ;;; C-c i         html-add-list-or-menu-item
  91. ;;;   Add a new list or menu item in a list or menu.  You are assumed
  92. ;;;   to be inside a list or menu (specifically, at the end of another
  93. ;;;   item).
  94. ;;;
  95. ;;; C-c l         html-add-normal-link
  96. ;;;   Add a link.  You will be prompted for the link (any string;
  97. ;;;   e.g., http://foo.bar/argh/blagh).  The cursor will be left where
  98. ;;;   you can type the text that will represent the link in the
  99. ;;;   document.
  100. ;;;
  101. ;;; C-c m         html-add-menu
  102. ;;;   Open a menu.  The initial item is created for you.  To create
  103. ;;;   additional items, use 'C-c i'.
  104. ;;;
  105. ;;; C-c p         html-add-paragraph-separator
  106. ;;;   Use this command at the end of each paragraph.
  107. ;;;
  108. ;;; C-c s         html-add-list
  109. ;;;   Open a list.  The initial item is created for you.  To create
  110. ;;;   additional items, use 'C-c i'.
  111. ;;;
  112. ;;; C-c t         html-add-title
  113. ;;;   Add a title to the document.  You will be prompted for the
  114. ;;;   contents of the title.  If a title already exists at the very
  115. ;;;   top of the document, the existing contents will be replaced.
  116. ;;;
  117. ;;; C-c x         html-add-plaintext
  118. ;;;   Add plaintext.  The cursor will be positioned where you can type
  119. ;;;   plaintext (or insert another file, or whatever).
  120. ;;;
  121. ;;; < > &
  122. ;;;   These are overridden to output <, >, and &
  123. ;;;   respectively.  The real characters <, >, and & can be entered
  124. ;;;   into the text either by prepending 'C-c' to the character or by
  125. ;;;   using the Emacs quoted-insert (C-q) command.
  126. ;;;
  127. ;;; C-c <, C-c >, C-c &
  128. ;;;   See '< > &' above.
  129. ;;;
  130. ;;; ---------------------------- ADDITIONAL NOTES ----------------------------
  131. ;;;
  132. ;;; If you are running Epoch or Lucid Emacs, highlighting will be used
  133. ;;; to deemphasize HTML message elements as they are created.  You can
  134. ;;; turn this off; see the source code.
  135. ;;;
  136. ;;; -------------------------------- GOTCHAS ---------------------------------
  137. ;;;
  138. ;;; HTML documents can be tricky.  html-mode is not smart enough to
  139. ;;; enforce correctness or sanity, so you have to do that yourself.
  140. ;;;
  141. ;;; In particular, html-mode is smart enough to generate unique
  142. ;;; numeric NAME id's for all links that were (1) created via an
  143. ;;; html-mode command or (2) present in the file when it was loaded.
  144. ;;; Any other links (e.g. links added via Emacs cut and paste) may
  145. ;;; have ID's that conflict with ID's html-mode generates.  You must
  146. ;;; watch for this and fix it when appropriate; otherwise, your
  147. ;;; hypertext document will not work correctly.
  148. ;;;
  149. ;;; ------------------------- WHAT HTML-MODE IS NOT --------------------------
  150. ;;;
  151. ;;; html-mode is not a mode for *browsing* HTML documents.  In
  152. ;;; particular, html-mode provides no hypertext capabilities.  There
  153. ;;; is a clear need for an HTML browser; if you write one, let me
  154. ;;; know.
  155. ;;;
  156. ;;; ------------------------------ WHAT HTML IS ------------------------------
  157. ;;;
  158. ;;; HTML (HyperText Markup Language) is a format for hypertext
  159. ;;; documents.  For more information on HTML, telnet to info.cern.ch.
  160. ;;;
  161. ;;; --------------------------------------------------------------------------
  162. ;;; LCD Archive Entry:
  163. ;;; html-mode|Marc Andreessen|marca@ncsa.uiuc.edu|
  164. ;;; Major mode for editing HTML hypertext files.|
  165. ;;; $Date: 1992/11/18 03:20:43 $|$Revision: 1.11 $|~/modes/html-mode.el.Z|
  166. ;;; --------------------------------------------------------------------------
  167.  
  168. (provide 'html-mode)
  169.  
  170. ;;; ------------------------------- variables --------------------------------
  171.  
  172. (defvar html-use-highlighting t
  173.   "*Flag to use highlighting for HTML directives in Epoch or Lucid Emacs; 
  174. if non-NIL, highlighting will be used.")
  175.  
  176. (defvar html-deemphasize-color "grey80"
  177.   "*Color for de-highlighting HTML directives in Epoch or Lucid Emacs.")
  178.  
  179. (defvar html-emphasize-color "yellow"
  180.   "*Color for highlighting HTML something-or-others in Epoch or Lucid Emacs.")
  181.  
  182. ;;; --------------------------------- setup ----------------------------------
  183.  
  184. (defvar html-mode-syntax-table nil
  185.   "Syntax table used while in html mode.")
  186.  
  187. (defvar html-mode-abbrev-table nil
  188.   "Abbrev table used while in html mode.")
  189. (define-abbrev-table 'html-mode-abbrev-table ())
  190.  
  191. (if html-mode-syntax-table
  192.     ()
  193.   (setq html-mode-syntax-table (make-syntax-table))
  194.   (modify-syntax-entry ?\" ".   " html-mode-syntax-table)
  195.   (modify-syntax-entry ?\\ ".   " html-mode-syntax-table)
  196.   (modify-syntax-entry ?' "w   " html-mode-syntax-table))
  197.  
  198. (defvar html-mode-map nil "")
  199. (if html-mode-map
  200.     ()
  201.   (setq html-mode-map (make-sparse-keymap))
  202.   (define-key html-mode-map "\t" 'tab-to-tab-stop)
  203.   (define-key html-mode-map "\C-ca" 'html-add-address)
  204.   (define-key html-mode-map "\C-cd" 'html-add-definition-list)
  205.   (define-key html-mode-map "\C-ce" 'html-add-definition-entry)
  206.   (define-key html-mode-map "\C-ch" 'html-add-header)
  207.   (define-key html-mode-map "\C-ci" 'html-add-list-or-menu-item)
  208.   (define-key html-mode-map "\C-cl" 'html-add-normal-link)
  209.   (define-key html-mode-map "\C-cm" 'html-add-menu)
  210.   (define-key html-mode-map "\C-cp" 'html-add-paragraph-separator)
  211.   (define-key html-mode-map "\C-cs" 'html-add-list)
  212.   (define-key html-mode-map "\C-ct" 'html-add-title)
  213.   (define-key html-mode-map "\C-cx" 'html-add-plaintext)
  214.   (define-key html-mode-map "<" 'html-less-than)
  215.   (define-key html-mode-map ">" 'html-greater-than)
  216.   (define-key html-mode-map "&" 'html-ampersand)
  217.   (define-key html-mode-map "\C-c<" 'html-real-less-than)
  218.   (define-key html-mode-map "\C-c>" 'html-real-greater-than)
  219.   (define-key html-mode-map "\C-c&" 'html-real-ampersand)
  220. )
  221.  
  222. ;;; --------------------------- buffer-local vars ----------------------------
  223.  
  224. (defvar html-link-counter-default 0)
  225. (defvar html-link-counter nil)
  226. (make-variable-buffer-local 'html-link-counter)
  227. (setq-default html-link-counter html-link-counter-default)
  228.  
  229. ;;; ------------------------------ highlighting ------------------------------
  230.  
  231. (defvar html-running-lemacs (string-match "Lucid" emacs-version)
  232.   "Non-nil if running Lucid Emacs.")
  233.  
  234. (defvar html-running-epoch (boundp 'epoch::version)
  235.   "Non-nil if running Epoch.")
  236.  
  237. (if (and html-running-epoch html-use-highlighting)
  238.     (progn
  239.       (defvar html-deemphasize-style (make-style))
  240.       (set-style-foreground html-deemphasize-style html-deemphasize-color)
  241.       (defvar html-emphasize-style (make-style))
  242.       (set-style-foreground html-emphasize-style html-emphasize-color)))
  243.  
  244. (if (and html-running-lemacs html-use-highlighting)
  245.     (progn
  246.       (defvar html-deemphasize-style (make-face 'html-deemphasize-face))
  247.       (set-face-foreground html-deemphasize-style html-deemphasize-color)
  248.       (defvar html-emphasize-style (make-face 'html-emphasize-face))
  249.       (set-face-foreground html-emphasize-style html-emphasize-color)))
  250.  
  251. (if html-use-highlighting
  252.     (progn
  253.       (if html-running-lemacs
  254.           (defun html-add-zone (start end style)
  255.             "Add a Lucid Emacs extent from START to END with STYLE."
  256.             (let ((extent (make-extent start end)))
  257.               (set-extent-face extent style)
  258.               (set-extent-data extent 'html-mode))))
  259.       (if html-running-epoch
  260.           (defun html-add-zone (start end style)
  261.             "Add an Epoch zone from START to END with STYLE."
  262.             (let ((zone (add-zone start end style)))
  263.               (epoch::set-zone-data zone 'html-mode))))))
  264.  
  265. (defun html-maybe-deemphasize-region (start end)
  266.   "Maybe deemphasize a region of text.  Region is from START to END."
  267.   (and (or html-running-epoch html-running-lemacs)
  268.        html-use-highlighting
  269.        (html-add-zone start end html-deemphasize-style)))
  270.  
  271. ;;; ----------------------------- link commands ------------------------------
  272.  
  273. (defun html-add-link (link-object)
  274.   "Add a link."
  275.   (let ((start (point)))
  276.     (setq html-link-counter (1+ html-link-counter))
  277.     (insert "<A NAME=" (format "%d" html-link-counter) 
  278.             " HREF=" link-object ">")
  279.     (html-maybe-deemphasize-region start (1- (point)))
  280.     (insert "</A>")
  281.     (push-mark)
  282.     (forward-char -4)
  283.     (html-maybe-deemphasize-region (1+ (point)) (+ (point) 4))))
  284.  
  285. (defun html-add-normal-link (link)
  286.   "Make a link.  There is no completion of any kind yet."
  287.   (interactive "sLink to: ")
  288.   (html-add-link link))
  289.  
  290. ;;; --------------------------- document elements ----------------------------
  291.  
  292. (defun html-add-title (title)
  293.   "Add or modify a title."
  294.   (interactive "sTitle: ")
  295.   (save-excursion
  296.     (goto-char (point-min))
  297.     (if (and (looking-at "<TITLE>")
  298.              (save-excursion
  299.                (forward-char 7)
  300.                (re-search-forward "[^<]*" 
  301.                                   (save-excursion (end-of-line) (point)) 
  302.                                   t)))
  303.         ;; Plop the new title in its place.
  304.         (replace-match title t)
  305.       (insert "<TITLE>")
  306.       (html-maybe-deemphasize-region (point-min) (1- (point)))
  307.       (insert title)
  308.       (insert "</TITLE>")
  309.       (html-maybe-deemphasize-region (- (point) 7) (point))
  310.       (insert "\n"))))
  311.  
  312. (defun html-add-header (size header)
  313.   "Add a header."
  314.   (interactive "sSize (1 or 2): \nsHeader: ")
  315.   (let ((start (point)))
  316.     (insert "<H" size ">")
  317.     (html-maybe-deemphasize-region start (1- (point)))
  318.     (insert header)
  319.     (setq start (point))
  320.     (insert "</H" size ">\n")
  321.     (html-maybe-deemphasize-region (1+ start) (1- (point)))))
  322.  
  323. (defun html-add-paragraph-separator ()
  324.   "Add a paragraph separator."
  325.   (interactive)
  326.   (let ((start (point)))
  327.     (insert "  <P>\n\n")
  328.     (html-maybe-deemphasize-region (+ start 2) (- (point) 2))))
  329.  
  330. (defun html-add-definition-list ()
  331.   "Add a definition list."
  332.   (interactive)
  333.   (let ((start (point)))
  334.     (insert "<DL>\n")
  335.     (html-maybe-deemphasize-region start (1- (point)))
  336.     (insert "<DT> ")
  337.     ;; Point goes right there.
  338.     (save-excursion
  339.       (insert "\n<DD> \n")
  340.       (setq start (point))
  341.       (insert "</DL>\n")
  342.       (html-maybe-deemphasize-region start (1- (point)))
  343.       ;; Mark goes after list -- this doesn't work.
  344.       (push-mark))))
  345.  
  346. (defun html-add-definition-entry ()
  347.   "Add a definition entry.  Assume we're at the end of a previous
  348. entry."
  349.   (interactive)
  350.   (let ((start (point)))
  351.     (insert "\n<DT> ")
  352.     (save-excursion
  353.       (insert "\n<DD> "))))
  354.  
  355. (defun html-add-plaintext ()
  356.   "Add plaintext."
  357.   (interactive)
  358.   (let ((start (point)))
  359.     (insert "<XMP>\n")
  360.     (html-maybe-deemphasize-region start (1- (point)))
  361.     (save-excursion
  362.       (insert "\n")
  363.       (setq start (point))
  364.       (insert "</XMP>\n")
  365.       (html-maybe-deemphasize-region start (1- (point)))
  366.       ;; This doesn't work.
  367.       (push-mark))))
  368.  
  369. (defun html-add-list-internal (type)
  370.   (let ((start (point)))
  371.     (insert "<" type ">\n")
  372.     (html-maybe-deemphasize-region start (1- (point)))
  373.     (insert "<LI> ")
  374.     ;; Point goes right there.
  375.     (save-excursion
  376.       (insert "\n")
  377.       (setq start (point))
  378.       (insert "</" type ">\n")
  379.       (html-maybe-deemphasize-region start (1- (point)))
  380.       ;; Mark goes after list -- this doesn't work.
  381.       (push-mark))))
  382.  
  383. (defun html-add-list ()
  384.   "Add a list."
  385.   (interactive)
  386.   (html-add-list-internal "UL"))
  387.  
  388. ;; Is this correct?  Viola doesn't seem to do anything with it.
  389. (defun html-add-menu ()
  390.   "Add a menu."
  391.   (interactive)
  392.   (html-add-list-internal "MENU"))
  393.  
  394. (defun html-add-list-or-menu-item ()
  395.   "Add a list or menu item.  Assume we're at the end of the
  396. last item."
  397.   (interactive)
  398.   (let ((start (point)))
  399.     (insert "\n<LI> ")))
  400.  
  401. (defun html-add-address ()
  402.   "Add an address."
  403.   (interactive)
  404.   (let ((start (point)))
  405.     (insert "<ADDRESS> ")
  406.     (html-maybe-deemphasize-region start (1- (point)))
  407.     (save-excursion
  408.       (setq start (point))
  409.       (insert "  </ADDRESS>\n")
  410.       (html-maybe-deemphasize-region (+ start 2) (1- (point)))
  411.       ;; Obviously this doesn't work here, so I don't
  412.       ;; see why you're being an idiot and still doing it
  413.       ;; like this....
  414.       (push-mark))))
  415.  
  416. (defun html-less-than ()
  417.   (interactive)
  418.   (insert "<"))
  419.  
  420. (defun html-greater-than ()
  421.   (interactive)
  422.   (insert ">"))
  423.  
  424. (defun html-ampersand ()
  425.   (interactive)
  426.   (insert "&"))
  427.  
  428. (defun html-real-less-than ()
  429.   (interactive)
  430.   (insert "<"))
  431.  
  432. (defun html-real-greater-than ()
  433.   (interactive)
  434.   (insert ">"))
  435.  
  436. (defun html-real-ampersand ()
  437.   (interactive)
  438.   (insert "&"))
  439.  
  440. ;;; ------------------------------- html-mode --------------------------------
  441.  
  442. (defun html-mode ()
  443.   "Major mode for editing HTML hypertext documents.  Special commands:\\{html-mode-map}
  444. Turning on html-mode calls the value of the variable html-mode-hook,
  445. if that value is non-nil."
  446.   (interactive)
  447.   (kill-all-local-variables)
  448.   (use-local-map html-mode-map)
  449.   (setq mode-name "Html")
  450.   (setq major-mode 'html-mode)
  451.   (setq local-abbrev-table html-mode-abbrev-table)
  452.   (set-syntax-table html-mode-syntax-table)
  453.   (run-hooks 'html-mode-hook))
  454.  
  455. ;;; ------------------------------- our hooks --------------------------------
  456.  
  457. (defun html-find-file-hook ()
  458.   "Hook called from find-file-hooks.  Set html-link-counter to 
  459. the highest link value in the document (the next link created will
  460. be one greater than that) to insure unique (numeric) link ID's."
  461.   (save-excursion
  462.     (goto-char (point-min))
  463.     (while (re-search-forward "<A NAME=" (point-max) t)
  464.       (let ((subst (buffer-substring (match-end 0)
  465.                                      (save-excursion
  466.                                        (re-search-forward " " (point-max) t)
  467.                                        (match-beginning 0)))))
  468.         (and subst
  469.              (> (string-to-int subst) html-link-counter)
  470.              (setq html-link-counter (string-to-int subst)))))))
  471.  
  472. ;;; ------------------------------- hook setup -------------------------------
  473.  
  474. ;; Author: Daniel LaLiberte (liberte@cs.uiuc.edu).
  475. (defun html-postpend-unique-hook (hook-var hook-function)
  476.   "Postpend HOOK-VAR with HOOK-FUNCTION, if it is not already an element.
  477. hook-var's value may be a single function or a list of functions."
  478.   (if (boundp hook-var)
  479.       (let ((value (symbol-value hook-var)))
  480.         (if (and (listp value) (not (eq (car value) 'lambda)))
  481.             (and (not (memq hook-function value))
  482.                  (set hook-var (append value (list hook-function))))
  483.           (and (not (eq hook-function value))
  484.                (set hook-var (append value (list hook-function))))))
  485.     (set hook-var (list hook-function))))
  486.  
  487. (postpend-unique-hook 'find-file-hooks 'html-find-file-hook)
  488.  
  489. ;;; ------------------------------ final setup -------------------------------
  490.  
  491. (or (assoc "\\.html$" auto-mode-alist)
  492.     (setq auto-mode-alist (cons '("\\.html$" . html-mode) auto-mode-alist)))
  493.